import { useEffect, useState, useCallback, useMemo } from "react";
import Taro, { useRouter } from "@tarojs/taro";
import { View, Image } from "@tarojs/components";
import { connect } from "react-redux";
import Lyric from "../../components/Lyric/Lyric";
import CSlider from "../../components/CSlider/CSlider";
import "./index.scss";
import { setPlaymode } from "../../redux/actions";
import { getSongInfo, getLikeMusicList, likeMusic } from "../../redux/async";
import classnames from "classnames";

const backgroundAudioManager = Taro.getBackgroundAudioManager();

function SongDetail(props) {
  const { id } = useRouter().params;
  const {
    isPlaying,
    dispatch,
    currentSongInfo,
    likeMusicList,
    playMode,
    canPlayList,
    currentSongIndex
  } = props;
  const [userInfo] = useState<any>(Taro.getStorageSync("userInfo") || {});
  const [isplay, setIsplay] = useState<boolean>(isPlaying);
  const [showLyric, setShowLyric] = useState<boolean>(false);
  const [lrc, setLrc] = useState({
    scroll: false,
    nolyric: false,
    uncollected: false,
    lrclist: []
  });
  const [lrcIndex, setLrcIndex] = useState<number>(0);
  const [playPercent, setPlayPercent] = useState<number>(0);
  const [currentPosition, setCurrentPosition] = useState<number>(0);
  useEffect(() => {
    if (userInfo && userInfo.account) {
      dispatch(getLikeMusicList(userInfo.account));
    }
    dispatch(getSongInfo(id));
  }, [userInfo]);
  useEffect(() => {
    currentSongInfo.id && setSongInfo(currentSongInfo);
  }, [currentSongInfo]);
  const initPlay = useCallback(() => {
    backgroundAudioManager.onTimeUpdate(() => {
      Taro.getBackgroundAudioPlayerState({
        success: res => {
          if (res.status !== 2) {
            updateProgress(res.currentPosition);
            setCurrentPosition(res.currentPosition);
          }
        }
      });
    });
    backgroundAudioManager.onPause(() => {
      setIsplay(false);
    });
    backgroundAudioManager.onPlay(() => {
      setIsplay(true);
    });
    backgroundAudioManager.onEnded(() => {
      const routes = Taro.getCurrentPages();
      const currentRoute = routes[routes.length - 1].route;
      // 如果在当前页面则直接调用下一首的逻辑，反之则触发nextSong事件
      if (currentRoute === "pages/songDetail/index") {
        playByMode(playMode);
      } else {
        Taro.eventCenter.trigger("nextSong");
      }
    });
  }, [lrc]);
  const setSongInfo = useCallback(songinfo => {
    try {
      const { name, al, url, lrcInfo } = songinfo;
      Taro.setNavigationBarTitle({
        title: name
      });
      backgroundAudioManager.title = name;
      backgroundAudioManager.coverImgUrl = al.picUrl;
      backgroundAudioManager.src = url;
      setLrc(lrcInfo);
      setIsplay(true);
      initPlay();
    } catch (err) {
      console.log("err", err);
      getNextSong();
    }
  }, []);
  const playByMode = useCallback((playMode: string) => {
    switch (playMode) {
      case "one":
        getCurrentSong();
        break;
      case "shuffle":
        getShuffleSong();
        break;
      // 默认按列表顺序播放
      default:
        getNextSong();
    }
  }, []);
  const getShuffleSong = useCallback(() => {
    let nextSongIndex = Math.floor(Math.random() * (canPlayList.length - 1));
    dispatch(getSongInfo(canPlayList[nextSongIndex].id));
  }, []);
  const getCurrentSong = useCallback(() => {
    setSongInfo(currentSongInfo);
  }, []);
  const getPrevSong = useCallback(() => {
    let prevSongIndex = currentSongIndex - 1;
    if (playMode === "shuffle") {
      getShuffleSong();
      return;
    }
    if (currentSongIndex === 0) {
      prevSongIndex = canPlayList.length - 1;
    }
    dispatch(getSongInfo(canPlayList[prevSongIndex].id));
  }, [currentSongIndex, canPlayList, playMode]);
  const getNextSong = useCallback(() => {
    let nextSongIndex = currentSongIndex + 1;
    if (playMode === "shuffle") {
      getShuffleSong();
      return;
    }
    if (currentSongIndex === canPlayList.length - 1) {
      nextSongIndex = 0;
    }
    dispatch(getSongInfo(canPlayList[nextSongIndex].id));
  }, [currentSongIndex, canPlayList, playMode]);
  useEffect(() => {
    let i = 0;

    if (lrc && !lrc.scroll && lrc.lrclist && lrc.lrclist.length > 0) {
      lrc.lrclist.forEach((item: any, index: number) => {
        if (item.lrc_sec <= currentPosition) {
          i = index;
        }
      });
      setLrcIndex(i);
    }
  }, [currentPosition, lrc]);
  const pauseMusic = useCallback(() => {
    backgroundAudioManager.pause();
    setIsplay(false);
  }, []);
  const playMusic = useCallback(() => {
    backgroundAudioManager.play();
    setIsplay(true);
  }, []);

  let playModeImg = require("../../assets/images/song/icn_loop_mode.png");
  if (playMode === "one") {
    playModeImg = require("../../assets/images/song/icn_one_mode.png");
  } else if (playMode === "shuffle") {
    playModeImg = require("../../assets/images/song/icn_shuffle_mode.png");
  }
  const percentChange = useCallback(
    e => {
      const { value } = e.detail;
      const { dt } = currentSongInfo;
      let currentPosition = Math.floor(((dt / 1000) * value) / 100);
      backgroundAudioManager.seek(currentPosition);
      backgroundAudioManager.play();
    },
    [currentSongInfo]
  );
  const percentChanging = useCallback(() => {
    backgroundAudioManager.pause();
  }, []);
  const star = useMemo(() => {
    return likeMusicList.includes(currentSongInfo.id);
  }, [likeMusicList, currentSongInfo]);
  function updateProgress(currentPosition) {
    setPlayPercent(
      Math.floor((currentPosition * 1000 * 100) / props.currentSongInfo.dt)
    );
  }
  const changePlayMode = useCallback(() => {
    let state = "";
    if (playMode === "loop") {
      state = "one";
    } else if (playMode === "one") {
      state = "shuffle";
    } else {
      state = "loop";
    }
    dispatch(setPlaymode(state));
  }, [playMode]);
  const tolikeMusic = useCallback(() => {
    dispatch(likeMusic(!star, currentSongInfo.id));
  }, [star, currentSongInfo]);
  return (
    <View className="song">
      <Image className="song-bg" src={currentSongInfo.al.picUrl} />
      <View className={classnames("song-music", { hidden: showLyric })}>
        <View className={classnames("song-main", { playing: isplay })}>
          <Image
            className="song-before"
            src={require("../../assets/images/aag.png")}
          />
          <View className="song-cover">
            <View
              className={classnames("song-imgbox circling", {
                zpause: !isplay
              })}
            >
              <Image
                className="song-imgcover"
                src={currentSongInfo.al.picUrl}
              />
            </View>
          </View>
        </View>
        <View
          className="song-lgour"
          onClick={() => {
            setShowLyric(true);
          }}
        >
          <View
            className={classnames("song-lgourcover circling", {
              zpause: !isplay
            })}
          ></View>
        </View>
      </View>
      <CSlider
        percent={playPercent}
        onChange={e => {
          percentChange(e);
        }}
        onChanging={() => {
          percentChanging();
        }}
      />
      <Lyric
        lrc={lrc}
        lrcIndex={lrcIndex}
        showLyric={showLyric}
        onTrigger={() => {
          setShowLyric(false);
        }}
      />
      <View className="song-bottom flex around middle">
        <Image
          onClick={() => {
            changePlayMode();
          }}
          src={playModeImg}
          className="song-ico"
        />
        <Image
          onClick={() => {
            getPrevSong();
          }}
          src={require("../../assets/images/ajh.png")}
          className="song-minico"
        />
        {isplay ? (
          <Image
            onClick={() => {
              pauseMusic();
            }}
            src={require("../../assets/images/ajd.png")}
            className="song-play"
          />
        ) : (
          <Image
            onClick={() => {
              playMusic();
            }}
            src={require("../../assets/images/ajf.png")}
            className="song-play"
          />
        )}
        <Image
          onClick={() => {
            getNextSong();
          }}
          src={require("../../assets/images/ajb.png")}
          className="song-minico"
        />
        <Image
          src={
            star
              ? require("../../assets/images/song/play_icn_loved.png")
              : require("../../assets/images/song/play_icn_love.png")
          }
          className="song-ico"
          onClick={() => {
            tolikeMusic();
          }}
        />
      </View>
    </View>
  );
}
SongDetail.config = {
  navigationBarTitleText: "我的"
};
export default connect(
  function mapStateToProps(state) {
    return state;
  },
  function mapDispatchToProps(dispatch) {
    return { dispatch };
  }
)(SongDetail);
